home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-01 / pct1-b.zip / A86.DOC < prev    next >
Text File  |  1990-08-10  |  17KB  |  433 lines

  1.  
  2.  
  3.  
  4.                                                                              1
  5.  
  6.                                       USING  A86
  7.  
  8.  
  9.              This is intended as a guide to get A86 to work for all the
  10.              programs in the Tutor. It only covers things that won't work or
  11.              things A86 does differently. It does not cover any of the
  12.              benign options like local labels. 
  13.  
  14.  
  15.              ===== CHAPTER 1
  16.  
  17.              You need to take your text editor and change the last line of the
  18.              template files. At the moment they read:
  19.  
  20.                  END start
  21.  
  22.              You may either eliminate the line or change it to:
  23.  
  24.                  END main
  25.  
  26.              If you don't, you will get this error message:
  27.  
  28.                   END start~40 Conflicting Multiple Definition Not Allowed~ 
  29.  
  30.              Do this for all the original template files, because this line
  31.              will always cause an error. You will find out why when you get to
  32.              Chapter 10.
  33.  
  34.              You should also insert the word PUBLIC just before the line with
  35.              ASSUME. Do this in all the template files.
  36.  
  37.                  PUBLIC
  38.                  ASSUME cs:CODESTUFF, ds:DATASTUFF
  39.  
  40.              You will find out why in Chapter 15.
  41.  
  42.  
  43.              A86 has some unusual defaults, so you need to change them when
  44.              you assemble a file. If your file is named myprog.asm, the
  45.              command line you want to use for the rest of this tutorial is:
  46.  
  47.                  >a86 +DOSX myprog.asm
  48.  
  49.              You must use the file extension .asm when you call the program.
  50.              You can make a batch file (let's call it QASM.BAT) which has:
  51.  
  52.                  a86 +DOSX  %1.asm
  53.  
  54.              Then all you need to do is:
  55.  
  56.                  >qasm myprog
  57.  
  58.              Those four options on the command line are:
  59.  
  60.  
  61.              ______________________
  62.  
  63.              The PC Assembler Tutor - Copyright (C) 1990 Chuck Nelson
  64.  
  65.  
  66.  
  67.  
  68.              The PC Assembler Tutor                                          2
  69.              ______________________
  70.  
  71.                  +D   numbers with leading 0s are default decimal
  72.                  +O   make an object file
  73.                  +S   don't create an ancillary symbol table
  74.                  +X   require specific declaration of external information
  75.  
  76.              They should be used from now on. When you are through with all
  77.              the chapters, you can decide whether you want to continue using
  78.              them all. If you are using D86, you need to eliminate the 'S'.
  79.              The declaration should be +DOX since you will need the symbol
  80.              table. 
  81.  
  82.  
  83.              ===== CHAPTER 2
  84.  
  85.              Please read all of chapter 2 before you read these comments.
  86.  
  87.  
  88.              The defaults and definitions are the same with two exceptions.
  89.              First, any number that begins with a '0' is hex by default. That
  90.              is, 22 is a decimal number and 022 is a hex number. This has some
  91.              serious side effects. Take the number:
  92.  
  93.                  0847d
  94.  
  95.              This is 847, right?  No. It is 0847Dh = 34,637. In Chapter 7 we
  96.              will use these binary numbers:
  97.  
  98.                  01001011b
  99.                  00000100b
  100.  
  101.              These should be 75 and 4 respectively, but A86 evaluates them as
  102.              01001011Bh = 268500992 and 0100Bh = 4107. Since half of the
  103.              binary numbers you use will start with a 0, half of your binary
  104.              numbers will be wildly incorrect. In order to correct the
  105.              situation, you need to put a +D on the command line. This is the
  106.              'D' of +DOSX. The D will insure that all numbers starting with 0
  107.              will be decimal. This gets rid of all the side effects.
  108.              Alternatively, you can put:
  109.  
  110.                  RADIX 10
  111.  
  112.              at the top of your files before any of the code or data. This has
  113.              the same effect. Of course, if you really do want hex numbers,
  114.              this can be overridden with a specific 'h' after any number.
  115.  
  116.  
  117.              There is another major problem with data definitions. Let's say
  118.              that you want the following definitions:
  119.  
  120.                  weight    dw    ?
  121.                  cost      dw    20
  122.                  profit    dw    ?
  123.  
  124.              but you forget to put in some of the initializations in your text
  125.              file (a situation which is not unknown):
  126.  
  127.                  weight    dw    
  128.  
  129.  
  130.  
  131.  
  132.              Using A86                                                       3
  133.              _________
  134.  
  135.                  cost      dw    
  136.                  profit    dw    ?
  137.  
  138.              All other assemblers will generate an error. You must either put
  139.              in an initial value or you must say that you want no initial
  140.              value (by putting in a question mark). Not only does A86 not
  141.              generate an error, it does something strange. If there is neither
  142.              initialization nor a question mark, A86 will calculate an address
  143.              for the variable but WILL ALLOCATE NO SPACE FOR IT. What this
  144.              means is that in our above example, 'weight', 'cost', and
  145.              'profit' will all be at the same memory address. 'Weight' and
  146.              'cost' will have the same address with no space allocation.
  147.              'Profit' will be at the same memory address too, but will have
  148.              space allocated for it.
  149.  
  150.              This is all done silently, so you don't know that this is being
  151.              done. There is no way to shut this off. You might be able to find
  152.              that this is happening by looking at the symbol table, but that
  153.              means that you suspect that it is happening. What you need to
  154.              do whenever you use A86 is:
  155.  
  156.                  ALWAYS CHECK ALL DATA TO MAKE SURE THAT IT IS INITIALIZED OR
  157.                  HAS A QUESTION MARK
  158.  
  159.  
  160.  
  161.              ===== CHAPTER 10
  162.  
  163.              We now come to some actual differences. A86 does not produce a
  164.              list file. You can read the justification for this in your
  165.              documentation. Does this make a difference? It would be nice to
  166.              have one, but we can normally live without it. Just follow what
  167.              is happening with the MASM listing. 
  168.  
  169.              p94 - ASSUME statements. Both TASM and MASM keep track of how you
  170.              want the segments to be referenced. A86 doesn't. It simply
  171.              ignores any ASSUME statements. This means that any segment
  172.              overrides must be coded into the text file with:
  173.  
  174.                  mov  cx, ss:variable4
  175.                  mov  cx, es:variable2
  176.                  mov  cx, ds:variable1
  177.                  mov  cx, cs:variable3
  178.  
  179.              A86 assumes that all code uses CS (which it must), and that all
  180.              data uses DS unless there is a specific segment override. Is this
  181.              a big imposition? Not really. If you use a segment register other
  182.              than DS, it is normally for dealing with arrays, and in those
  183.              cases you need a segment override anyways. You will find out
  184.              about that in the next chapter.
  185.  
  186.              p97 - END statements. END is not necessary in A86. It knows that
  187.              the end has come when the file is finished. The default starting
  188.              point for an A86 file is the label 'main'. If A86 sees a label
  189.              name after an END statement, then it RENAMES that word 'main',
  190.              and renames all occurances of that word in the file 'main'. It
  191.              does not change the default starting name. This means that if you
  192.  
  193.  
  194.  
  195.  
  196.              The PC Assembler Tutor                                          4
  197.              ______________________
  198.  
  199.              have a statement like:
  200.  
  201.                  END start
  202.  
  203.              and you also have the label 'main' in your file, A86 will change
  204.              all occurances of 'start' to 'main', causing multiple use of the
  205.              same label.
  206.  
  207.  
  208.              ======== Chapter 15
  209.  
  210.              p154 - You do not need PUSHREGS and POPREGS. With A86, PUSH is
  211.              exactly the macro PUSHREGS:
  212.  
  213.                  PUSHREGS ax, bx, cx, dx, si
  214.                  PUSH     ax, bx, cx, dx, si
  215.  
  216.              These are exactly the same. POP shows the actual order that
  217.              things will be popped, while POPREGS has the reverse order so
  218.              that you can use a word processor to copy the PUSHREGS part. For
  219.              the above PUSH declaration, this is the correct POP:
  220.  
  221.                  POP     si, dx, cx, bx, ax
  222.                  POPREGS ax, bx, cx, dx, si
  223.  
  224.              From now on, whenever you see PUSHREGS, change it to PUSH, and
  225.              whenever you see POPREGS, change it to POP but reverse the order
  226.              of registers so that it is the actual order in which things are
  227.              POPped. You can delete the line:
  228.  
  229.                  include \pushregs.mac
  230.  
  231.              from your template file.
  232.  
  233.              ; - - - - - - - - - -
  234.  
  235.              Please read the whole chapter before reading the rest of these
  236.              comments.
  237.  
  238.              For some reason, A86 makes ALL normal variables and labels PUBLIC
  239.              unless you specifically tell it not to. The whole thrust of
  240.              programming for the last 20 years (PASCAL, C, and all structured
  241.              languages), has been to make NOTHING public unless specifically
  242.              requested, so this is an unwelcome default setting. You turn it
  243.              off by naming any normal (but not local) variable PUBLIC. In
  244.              fact, if you use the word PUBLIC alone:
  245.  
  246.                  PUBLIC
  247.  
  248.              without any name after it, A86 will turn this off. That is why
  249.              you put it in all the template files. Always have this in all
  250.              your assembler files.
  251.  
  252.  
  253.              A86 also assumes that any variable that has no data declaration
  254.              is EXTRN. This is a bad policy. What will happen is the
  255.              following. You are using the variable 'last_occurance' and you
  256.  
  257.  
  258.  
  259.  
  260.              Using A86                                                       5
  261.              _________
  262.  
  263.              misspell it 'last_ocurrance'. A86 sees no data declaration so
  264.              assumes that it is an external variable and assembles the file.
  265.              Three hours later you link the 6 modules of your program together
  266.              and you get a link error. The linker cannot find 'last_ocurrance'
  267.              anywhere. 
  268.  
  269.              Just as you should need to explicitly name things PUBLIC, you
  270.              should need to explicitly name things EXTRN. You do this by
  271.              putting +X (forced external declarations) on the command line.
  272.              This is the 'X' in the '+DOSX' that you have been using on the
  273.              command line.
  274.  
  275.  
  276.              ===== CHAPTER 21
  277.  
  278.              You need to change the ORG statement so it is in front of main
  279.  
  280.                  ORG 100h
  281.                  main proc near
  282.  
  283.              This is because you are using main as the starting address, so it
  284.              must be at 100h. This 100h is optional with A86. If it is making
  285.              a .COM file it automatically starts at 100h. A86 is designed to
  286.              give you a .COM file directly, so all you need to do with a
  287.              single file is:
  288.  
  289.                  >a86 +DS   myfile.asm
  290.  
  291.              and you will get MYFILE.COM as the output file. In the example
  292.              where we make a .COM file from multiple files, these files are
  293.              set up to be .OBJ files. If you want to make them into a .COM
  294.              file directly, you need to take out all PUBLIC, EXTRN and END
  295.              statements (and adjust PUSHREGS and POPREGS) and then do:
  296.  
  297.                  >a86 +DS  prog1.asm prog2.asm prog3.asm
  298.  
  299.              making sure that prog1.asm is first. The output file should be
  300.              prog1.com.
  301.  
  302.  
  303.              ===== CHAPTER 26
  304.  
  305.              You need to read all of Chapter 26 before reading any of the
  306.              following.
  307.  
  308.              A86 will work fine with any standard segment definitions. It also
  309.              has two special segment statements of its own. The first:
  310.  
  311.                  CODE SEGMENT
  312.  
  313.              will generate the following:
  314.  
  315.                  _TEXT SEGMENT PUBLIC 'CODE'
  316.  
  317.              The second statement:
  318.  
  319.                  DATA SEGMENT
  320.  
  321.  
  322.  
  323.  
  324.              The PC Assembler Tutor                                          6
  325.              ______________________
  326.  
  327.  
  328.              is NOT a segment declaration. It generates NO segment, it
  329.              allocates NO space and it initializes NO data. What is it? I'll
  330.              explain how it operates, but I have no idea why it exists. 
  331.  
  332.              The first time you use the 'DATA SEGMENT' instruction in a file
  333.              it is followed by ORG:
  334.  
  335.                  DATA SEGMENT
  336.                  ORG 1000h
  337.  
  338.              ORG relocates the counter for where the assembler is allocating
  339.              space in memory. From this point on, every time you define
  340.              variables:
  341.  
  342.                  time         dw   ?
  343.                  distance     dw   ?
  344.                  space        dw   ?
  345.  
  346.              A86 generates an distinct address for each variable. However, it
  347.              ALLOCATES NO SPACE. This is just an address that the code can use
  348.              when it refers to the variables. If you have the following
  349.              variables:
  350.  
  351.                  year        dw    1990
  352.                  prime       dw    73
  353.                  cost        dw    5167
  354.  
  355.              A86 will generate address for these variables but (1) will
  356.              allocate NO space, (2) will do NOTHING with those initializing
  357.              values and (3) WILL NOT COMPLAIN that you have tried using
  358.              initialized data in a DATA SEGMENT statement. A86 will do the
  359.              equivalent of:
  360.  
  361.                  year        dw    ?
  362.                  prime       dw    ?
  363.                  cost        dw    ?
  364.  
  365.              This data is technically in the CODE SEGMENT. If the code is
  366.              longer than that initial ORG number, some of the code will be in
  367.              the same place as some of the data and if you write to the data
  368.              you will overwrite the code. A86 will not complain. 
  369.  
  370.              For instance, we had ORG 1000h (4096d). If the code is 6000 bytes
  371.              long, the last 2000 bytes of code will share the space with the
  372.              data. This leads to either bad data or bad code or both.
  373.  
  374.              Why have this? Well, when DOS loads a .COM file into memory, it
  375.              uses ALL of memory. If I have:
  376.  
  377.                  INTSCRN.COM     541   07/23/90  17:45
  378.  
  379.              a .COM file that is 541 bytes long, DOS will allocate about
  380.              550,000 bytes for it on my computer. 549,459 bytes of this are
  381.              wasted space. It is A86's idea to put data in this wasted space. 
  382.              There is no reason for this, so don't do it. If you have a .COM
  383.              file, put all your data in the CODE SEGMENT. If you have an .OBJ
  384.  
  385.  
  386.  
  387.  
  388.              Using A86                                                       7
  389.              _________
  390.  
  391.              file you need to create a legitimate SEGMENT for the DATA. Its
  392.              name cannot be:
  393.  
  394.                  DATA  SEGMENT  PUBLIC 'DATA'
  395.  
  396.              If I have the following program:
  397.  
  398.                  ; - - - - - - - - - - - - - - -
  399.                  DATA SEGMENT PUBLIC 
  400.                  data1   db  "This is the output string", 13, 10, "$" 
  401.                  data2   db  100 dup (0) 
  402.                  ENDS 
  403.  
  404.                  CODE SEGMENT 
  405.  
  406.                  main: 
  407.                          mov     ax, seg DATA
  408.                          mov     ds, ax 
  409.               
  410.                          mov     ah, 09h         ; print string 
  411.                          lea     dx, data1 
  412.                          int     21h 
  413.  
  414.                          mov     ax, 4C00h       ; exit 
  415.                          int     21h 
  416.                  ; - - - - - - - - - - - - - - - 
  417.  
  418.              and I try to make an object file with it, I get the following
  419.              error:
  420.  
  421.                       mov  ax, seg DATA~61 Overlapping Local Not Allowed~ 
  422.  
  423.              The ability to put the segment starting address in the segment
  424.              register is a minimal requirement for doing anything. This
  425.              effectively eliminates the possibility of using DATA as the name
  426.              for a segment. Therefore, those of you who use Turbo Pascal need
  427.              to use:
  428.  
  429.                  DSEG  SEGMENT PUBLIC
  430.  
  431.              as an alternative. This will work with no problems.
  432.  
  433.